import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

/// 键盘工具类
/// 提供隐藏键盘的各种方法
class KeyboardUtil {
  KeyboardUtil._(); // 私有构造函数，防止实例化

  /// 隐藏键盘 - 推荐使用此方法
  static void hideKeyboard([BuildContext? context]) {
    // 方法1: 使用 FocusScope
    FocusManager.instance.primaryFocus?.unfocus();

    // 方法2: 如果有上下文，使用 FocusScope.of(context)
    if (context != null) {
      FocusScope.of(context).unfocus();
    }

    // 方法3: 系统通道方法（备用）
    SystemChannels.textInput.invokeMethod('TextInput.hide');
  }

  /// 通过失去焦点隐藏键盘
  static void hideKeyboardByUnfocus([BuildContext? context]) {
    if (context != null) {
      FocusScope.of(context).unfocus();
    } else {
      FocusManager.instance.primaryFocus?.unfocus();
    }
  }

  /// 通过系统通道强制隐藏键盘
  static void hideKeyboardBySystem() {
    SystemChannels.textInput.invokeMethod('TextInput.hide');
  }

  /// 在滚动时隐藏键盘
  static void hideKeyboardOnScroll(ScrollController scrollController, [BuildContext? context]) {
    scrollController.addListener(() {
      if (scrollController.position.hasContentDimensions &&
          scrollController.position.outOfRange) {
        hideKeyboard(context);
      }
    });
  }

  /// 创建滚动时隐藏键盘的监听器
  static NotificationListener<ScrollNotification> createScrollHideKeyboardListener({
    required Widget child,
    VoidCallback? onHide,
    BuildContext? context,
  }) {
    return NotificationListener<ScrollNotification>(
      onNotification: (ScrollNotification notification) {
        if (notification is ScrollStartNotification ||
            notification is ScrollUpdateNotification) {
          hideKeyboard(context);
          onHide?.call();
        }
        return false;
      },
      child: child,
    );
  }

  /// 创建点击外部隐藏键盘的包装器
  static Widget createTapHideKeyboardWrapper({
    required Widget child,
    VoidCallback? onHide,
    BuildContext? context,
  }) {
    return GestureDetector(
      onTap: () {
        hideKeyboard(context);
        onHide?.call();
      },
      behavior: HitTestBehavior.translucent,
      child: child,
    );
  }

  /// 检查键盘是否显示
  static bool isKeyboardVisible(BuildContext context) {
    return MediaQuery.of(context).viewInsets.bottom > 0;
  }

  /// 添加键盘显示/隐藏监听器
  static void addKeyboardListener({
    required BuildContext context,
    required VoidCallback onShow,
    required VoidCallback onHide,
  }) {
    // 使用 MediaQuery 监听视图Insets变化
    final mediaQuery = MediaQuery.of(context);
    double lastBottomInset = mediaQuery.viewInsets.bottom;

    // 创建一个监听器
    // 注意：这需要在有状态组件中使用，这里只是提供思路
    // 实际使用时可以在 StatefulWidget 的 didChangeDependencies 中实现
  }
}

/// 扩展方法，为 Widget 添加隐藏键盘功能
extension KeyboardHideExtension on Widget {
  /// 包装 widget，使其在点击时隐藏键盘
  Widget withKeyboardHideOnTap({BuildContext? context, VoidCallback? onHide}) {
    return KeyboardUtil.createTapHideKeyboardWrapper(
      child: this,
      context: context,
      onHide: onHide,
    );
  }

  /// 包装 widget，使其在滚动时隐藏键盘
  Widget withKeyboardHideOnScroll({BuildContext? context, VoidCallback? onHide}) {
    return KeyboardUtil.createScrollHideKeyboardListener(
      child: this,
      context: context,
      onHide: onHide,
    );
  }
}

/// 专门用于搜索页面的键盘管理工具
class SearchKeyboardManager {
  final TextEditingController searchController;
  final FocusNode searchFocusNode;
  final ScrollController? scrollController;
  final BuildContext? context;

  SearchKeyboardManager({
    required this.searchController,
    required this.searchFocusNode,
    this.scrollController,
    this.context,
  });

  /// 隐藏键盘并清空搜索
  void hideAndClear() {
    KeyboardUtil.hideKeyboard(context);
    searchController.clear();
  }

  /// 只隐藏键盘
  void hideOnly() {
    KeyboardUtil.hideKeyboard(context);
  }

  /// 设置滚动时隐藏键盘
  void setupScrollHide() {
    if (scrollController != null) {
      KeyboardUtil.hideKeyboardOnScroll(scrollController!, context);
    }
  }

  /// 处理搜索框外部的点击
  Widget buildWithHideOnTap(Widget child) {
    return KeyboardUtil.createTapHideKeyboardWrapper(
      child: child,
      context: context,
      onHide: hideOnly,
    );
  }
}